package com.findtech.threePomelos.net;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.avos.avoscloud.AVException;
import com.avos.avoscloud.AVObject;
import com.avos.avoscloud.AVQuery;
import com.avos.avoscloud.AVUser;
import com.avos.avoscloud.FindCallback;
import com.avos.avoscloud.GetCallback;
import com.avos.avoscloud.SaveCallback;
import com.findtech.threePomelos.base.MyApplication;
import com.findtech.threePomelos.database.OperateDBUtils;
import com.findtech.threePomelos.entity.BabyInfoEntity;
import com.findtech.threePomelos.entity.TravelInfoEntity;
import com.findtech.threePomelos.utils.RequestUtils;
import com.findtech.threePomelos.utils.Tools;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Created by zhi.zhang on 3/9/16.
 */
public class NetWorkRequest {
    private final String TAG = "NetWorkRequest";

    /* 表名 */
    /**
     * 宝贝信息
     */
    public static final String BABY_INFO = "BabyInfo";
    /**
     * 宝贝体重
     */
    public static final String BABY_WEIGHT = "BabyWeight";
    /**
     * 宝贝身高
     */
    public static final String BABY_HEIGHT = "BabyHeight";
    /**
     * 推车今日里程、今日时速、总里程
     */
    public static final String TRAVEL_INFO = "TravelInfo";
    /**
     * 推车总里程
     */
    public static final String TOTAL_MILEAGE = "TotalMileage";
    /**
     * 健康合理区间表
     */
    public static final String HEALTH_STATE = "HealthState";
    /**
     * 健康贴士
     */
    public static final String HEALTH_TIPS = "HealthTips";
    /**
     * 用户协议
     */
    public static final String USER_PROTOCOL = "UserProtocol";


    /* 健康贴士表中的列，宝贝健康小贴士中的文件 */
    /**
     * 健康贴士:文件
     */
    public static final String FILE_HEALTH_TIPS = "HealthTipsFile";
    /**
     * 育儿要点:文件
     */
    public static final String FILE_CHILDCARE_POINTS = "ChildcarePoints";
    /**
     * 发育体征:文件
     */
    public static final String FILE_DEVELOPMENT_SIGNS = "DevelopmentSigns";
    /**
     * 科普提示:文件
     */
    public static final String FILE_SCIENCE_TIP = "ScienceTip";
    /**
     * 成长关注:文件
     */
    public static final String FILE_GROWN_CONCERN = "GrownConcern";
    /**
     * 亲子互动:文件
     */
    public static final String FILE_PARENTAL = "ParentalInteraction";
    /**
     * 育儿要点预览:字符串
     */
    public static final String TIPS_PREVIEW = "TipsPreview";

    public static final String HEIGHT_RANGE = "heightRange";
    public static final String WEIGHT_RANGE = "weightRange";


    private boolean isSavedTheTime = false; //是否已经有这个时间的体重
    private List<AVObject> listAVObject;
    private Context mContext;
    private OperateDBUtils mOperateDBUtils;
    private ProgressDialog progressDialog;
    private AVObject postIsBind;
    private BabyInfoEntity babyInfoEntity = BabyInfoEntity.getInstance();

    public NetWorkRequest(Context context) {
        mContext = context;
        mOperateDBUtils = new OperateDBUtils(mContext);
        initProgressDialog();
    }

    public void getBabyInfoDataAndSaveToDB() {
        AVQuery<AVObject> query = AVQuery.getQuery(BABY_INFO);
        query.whereEqualTo("post", AVUser.getCurrentUser());
        query.findInBackground(new FindCallback<AVObject>() {
            @Override
            public void done(List<AVObject> list, AVException e) {
                if (e == null) {
                    if (list.size() == 0) {//如果服务器中没有这个用户数据，就创建一个
                        AVObject post = new AVObject(NetWorkRequest.BABY_INFO);
                        post.put("post", AVUser.getCurrentUser());
                        post.saveInBackground(new SaveCallback() {
                            @Override
                            public void done(AVException e) {
                                if (e == null) {
                                    Log.d(TAG, "SetBabyBirthdayActivity  ");
                                    getBabyInfoDataAndSaveToDB();
                                } else {
                                    mOperateDBUtils.queryBabyInfoDataFromDB();
                                    Log.d(TAG, "SetBabyBirthdayActivity AVException e = " + e);
                                    e.printStackTrace();
                                }
                            }
                        });
                    } else {
                        mOperateDBUtils.saveBabyInfoDataToDB(list);
                        Log.d(TAG, "NetWorkRequest findInBackground done");
                    }
                } else {
                    mOperateDBUtils.queryBabyInfoDataFromDB();
                    Log.d(TAG, "NetWorkRequest findInBackground e = " + e);
                }
            }
        });
    }

    public void getBabyInfoDataAndSaveToDB(final QueryBabyInfoCallBack.QueryIsBind queryIsBind) {
        AVQuery<AVObject> query = AVQuery.getQuery(BABY_INFO);
        query.whereEqualTo("post", AVUser.getCurrentUser());
        query.findInBackground(new FindCallback<AVObject>() {
            @Override
            public void done(List<AVObject> list, AVException e) {
                if (e == null) {
                    if (list.size() == 0) {//如果服务器中没有这个用户数据，就创建一个
                        AVObject post = new AVObject(NetWorkRequest.BABY_INFO);
                        post.put("post", AVUser.getCurrentUser());
                        post.saveInBackground(new SaveCallback() {
                            @Override
                            public void done(AVException e) {
                                if (e == null) {
                                    Log.d(TAG, "SetBabyBirthdayActivity  ");
                                    getBabyInfoDataAndSaveToDB(queryIsBind);
                                } else {
                                    mOperateDBUtils.queryBabyInfoDataFromDB();
                                    Log.d(TAG, "SetBabyBirthdayActivity AVException e = " + e);
                                    e.printStackTrace();
                                }
                            }
                        });
                    } else {
                        mOperateDBUtils.saveBabyInfoDataToDB(list);
                        if (list != null && list.size() > 0) {
                            queryIsBind.finishQueryIsBind(list.get(0).getBoolean(OperateDBUtils.IS_BIND),
                                    list.get(0).getString(OperateDBUtils.BLUETOOTH_DEVICE_ID));
                            Log.d(TAG, "finishQueryIsBind");
                        } else {
                            queryIsBind.finishQueryIsBind(false,"");
                            Log.d(TAG, "finishQueryIsBind 1");
                        }
                        Log.d(TAG, "NetWorkRequest findInBackground done 1");
                    }
                } else {
                    mOperateDBUtils.queryBabyInfoDataFromDB();
                    Log.d(TAG, "NetWorkRequest findInBackground e = " + e);
                }
            }
        });
    }

    public void getBabyWeightDataAndSaveToDB() {
        AVQuery<AVObject> query = AVQuery.getQuery(BABY_WEIGHT);
        query.whereEqualTo("post", AVUser.getCurrentUser());
        query.orderByAscending(OperateDBUtils.DATE);//按时间，升序排列
        query.findInBackground(new FindCallback<AVObject>() {
            @Override
            public void done(List<AVObject> list, AVException e) {
                if (e == null) {
                    mOperateDBUtils.clearDBTable(OperateDBUtils.WEIGHT_URI);
                    if (list.size() > 0) {
                        for (AVObject avObject : list) {
                            String weight = avObject.getString(OperateDBUtils.WEIGHT);
                            Date date = avObject.getDate(OperateDBUtils.DATE);
                            String time = Tools.getTimeFromDate(date);
                            if (!TextUtils.isEmpty(weight) && !TextUtils.isEmpty(time)) {
                                mOperateDBUtils.saveWeightToDB(weight, time);
                            }
                        }
                    }
                    mOperateDBUtils.queryUserWeightData();
                } else {
                    mOperateDBUtils.queryUserWeightData();
                    Log.d("ZZ", "getBabyWeightDataAndSaveToDB e = " + e);
                }
            }
        });
    }


    public void getBabyHeightDataAndSaveToDB() {
        AVQuery<AVObject> query = AVQuery.getQuery(BABY_HEIGHT);
        query.whereEqualTo("post", AVUser.getCurrentUser());
        query.orderByAscending(OperateDBUtils.DATE);//按时间，升序排列
        query.findInBackground(new FindCallback<AVObject>() {
            @Override
            public void done(List<AVObject> list, AVException e) {
                if (e == null) {
                    mOperateDBUtils.clearDBTable(OperateDBUtils.HEIGHT_URI);
                    if (list.size() > 0) {
                        for (AVObject avObject : list) {
                            String height = avObject.getString(OperateDBUtils.HEIGHT);
                            Date curDate = avObject.getDate(OperateDBUtils.DATE);
                            String time = Tools.getTimeFromDate(curDate);
                            if (!TextUtils.isEmpty(height) && !TextUtils.isEmpty(time)) {
                                mOperateDBUtils.saveHeightToDB(height, time);
                            }
                        }
                    }
                    mOperateDBUtils.queryUserHeightData();
                } else {
                    mOperateDBUtils.queryUserHeightData();
                    Log.d("ZZ", "getBabyHeightDataAndSaveToDB e = " + e);
                }
            }
        });
    }

    public void getTotalMileageDataAndSaveToSP() {
        AVQuery<AVObject> query = AVQuery.getQuery(TOTAL_MILEAGE);
        query.whereEqualTo("post", AVUser.getCurrentUser());
        query.findInBackground(new FindCallback<AVObject>() {
            TravelInfoEntity travelInfoEntity = TravelInfoEntity.getInstance();

            @Override
            public void done(List<AVObject> list, AVException e) {
                String todayMileage = "0.0";
                if (e == null) {
                    if (list.size() > 0) {
                        for (AVObject avObject : list) {
                            todayMileage = avObject.getString(OperateDBUtils.TOTAL_MILEAGE);
                        }
                    }
                    RequestUtils.getSharepreferenceEditor(mContext).putString(OperateDBUtils.TOTAL_MILEAGE,
                            todayMileage).commit();
                } else {
                    todayMileage = RequestUtils.getSharepreference(mContext).getString(OperateDBUtils.TOTAL_MILEAGE, "0.0");
                    Log.d("ZZ", "getBabyHeightDataAndSaveToDB e = " + e);
                }
                travelInfoEntity.setTotalMileage(todayMileage);
                mHandle.sendEmptyMessage(0x99);
            }
        });
    }

    Handler mHandle = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            Intent intent = new Intent(OperateDBUtils.QUERY_FINISH);
            mContext.sendBroadcast(intent);
            return true;
        }
    });

    public void getTravelInfoDataAndSaveToDB() {
        AVQuery<AVObject> query = AVQuery.getQuery(TRAVEL_INFO);
        query.whereEqualTo("post", AVUser.getCurrentUser());
        final Date curDate = Tools.getCurrentDate();
        query.whereEqualTo(OperateDBUtils.DATE, curDate);
        query.findInBackground(new FindCallback<AVObject>() {
            @Override
            public void done(List<AVObject> list, AVException e) {
                if (e == null) {
                    mOperateDBUtils.deleteTimeDBTable(OperateDBUtils.TABLE_TRAVEL_URI, Tools.getTimeFromDate(curDate));
                    if (list.size() > 0) {
                        for (AVObject avObject : list) {
                            TravelInfoEntity travelInfoEntity = TravelInfoEntity.getInstance();
                            travelInfoEntity.setTodayMileage(avObject.getString(OperateDBUtils.TODAY_MILEAGE));
                            travelInfoEntity.setAverageSpeed(avObject.getString(OperateDBUtils.AVERAGE_SPEED));
                            Date date = avObject.getDate(OperateDBUtils.DATE);
                            mOperateDBUtils.saveTravelInfoToDB(travelInfoEntity, Tools.getTimeFromDate(date));
                        }
                    }
                    mHandle.sendEmptyMessage(0x99);
                } else {
                    mOperateDBUtils.queryTravelInfoDataFromDB();
                    Log.d("ZZ", "getBabyHeightDataAndSaveToDB e = " + e);
                }
            }
        });
    }

    /**
     * @param tableName BABY_WEIGHT
     *                  BABY_HEIGHT
     *                  TRAVEL_INFO
     * @param date
     * @return
     */

    public void isExistTheTimeOnTable(String tableName, final Date date, final FindCallback findCallback) {
        final AVQuery<AVObject> query = AVQuery.getQuery(tableName);
        query.whereEqualTo("post", AVUser.getCurrentUser());
        query.whereEqualTo(OperateDBUtils.DATE, date);
        query.findInBackground(findCallback);
    }

    public void isExistTheUserOnTable(String tableName, final FindCallback<AVObject> findCallback) {
        final AVQuery<AVObject> query = AVQuery.getQuery(tableName);
        query.whereEqualTo("post", AVUser.getCurrentUser());
        query.findInBackground(findCallback);
    }

    public void updateWeightAndTimeToServer(final String weight, final Date date, final SaveCallback saveCallback) {
        if (TextUtils.isEmpty(weight) || date == null) {
            Log.d(TAG, "updateWeightAndTimeToServer weight =  " + weight + " , date = " + date);
            return;
        }
        final AVQuery<AVObject> query = AVQuery.getQuery(BABY_WEIGHT);
        query.whereEqualTo("post", AVUser.getCurrentUser());
        query.whereEqualTo(OperateDBUtils.DATE, date);
        query.findInBackground(new FindCallback<AVObject>() {
            @Override
            public void done(List<AVObject> list, AVException e) {
                if (e == null) {
                    if (list.size() > 0) {
                        for (int i = 0; i < list.size(); i++) {
                            AVObject avObjects = list.get(i);
                            avObjects.put(OperateDBUtils.WEIGHT, weight);
                            avObjects.saveInBackground(saveCallback);
                        }
                    }
                }
            }
        });
    }

    public void addWeightAndTimeToServer(final String weight, final Date date, final SaveCallback saveCallback) {
        if (TextUtils.isEmpty(weight) || date == null) {
            Log.d(TAG, "addWeightAndTimeToServer weight =  " + weight + " , date = " + date);
            return;
        }

        AVObject postWeight = new AVObject(BABY_WEIGHT);
        postWeight.put("post", AVUser.getCurrentUser());
        postWeight.put(OperateDBUtils.DATE, date);
        postWeight.put(OperateDBUtils.WEIGHT, weight);
        postWeight.saveInBackground(saveCallback);
    }

    public void updateHeightAndTimeToServer(final String height, final Date date, final SaveCallback saveCallback) {
        if (TextUtils.isEmpty(height) || date == null) {
            Log.d(TAG, "updateHeightAndTimeToServer height =  " + height + " , date = " + date);
            return;
        }
        final AVQuery<AVObject> query = AVQuery.getQuery(BABY_HEIGHT);
        query.whereEqualTo("post", AVUser.getCurrentUser());
        query.whereEqualTo(OperateDBUtils.DATE, date);
        query.findInBackground(new FindCallback<AVObject>() {
            @Override
            public void done(List<AVObject> list, AVException e) {
                if (e == null) {
                    if (list.size() > 0) {
                        for (int i = 0; i < list.size(); i++) {
                            AVObject avObjects = list.get(i);
                            avObjects.put(OperateDBUtils.HEIGHT, height);
                            avObjects.saveInBackground(saveCallback);
                        }
                    }
                }
            }
        });
    }

    public void addHeightAndTimeToServer(final String height, final Date date, final SaveCallback saveCallback) {
        if (TextUtils.isEmpty(height) || date == null) {
            Log.d(TAG, "addHeightAndTimeToServer height =  " + height + " , date = " + date);
            return;
        }

        AVObject postHeight = new AVObject(BABY_HEIGHT);
        postHeight.put("post", AVUser.getCurrentUser());
        postHeight.put(OperateDBUtils.DATE, date);
        postHeight.put(OperateDBUtils.HEIGHT, height);
        postHeight.saveInBackground(saveCallback);
    }

    public void updateTotalMileageAndTimeToServer(final String totalMileage, final SaveCallback saveCallback) {
        if (TextUtils.isEmpty(totalMileage)) {
            Log.d(TAG, "updateTotalMileageAndTimeToServer totalMileage =  " + totalMileage);
            return;
        }
        final AVQuery<AVObject> query = AVQuery.getQuery(TOTAL_MILEAGE);
        query.whereEqualTo("post", AVUser.getCurrentUser());
        query.findInBackground(new FindCallback<AVObject>() {
            @Override
            public void done(List<AVObject> list, AVException e) {
                if (e == null) {
                    if (list.size() > 0) {
                        for (int i = 0; i < list.size(); i++) {
                            AVObject avObjects = list.get(i);
                            avObjects.put(OperateDBUtils.TOTAL_MILEAGE, totalMileage);
                            avObjects.saveInBackground(saveCallback);
                        }
                    }
                }
            }
        });
    }

    public void addTotalMileageAndTimeToServer(final String totalMileage, final SaveCallback saveCallback) {
        if (TextUtils.isEmpty(totalMileage)) {
            Log.d(TAG, "addTotalMileageAndTimeToServer totalMileage =  " + totalMileage);
            return;
        }
        AVObject postTotalMileage = new AVObject(TOTAL_MILEAGE);
        postTotalMileage.put("post", AVUser.getCurrentUser());
        postTotalMileage.put(OperateDBUtils.TOTAL_MILEAGE, totalMileage);
        postTotalMileage.saveInBackground(saveCallback);
    }

    public void updateTravelInfoAndTimeToServer(final TravelInfoEntity travelInfoEntity, final Date date, final SaveCallback saveCallback) {
        if (travelInfoEntity == null || date == null) {
            Log.d(TAG, "updateTravelInfoAndTimeToServer travelInfoEntity =  " + travelInfoEntity + " , date = " + date);
            return;
        }
        final AVQuery<AVObject> query = AVQuery.getQuery(TRAVEL_INFO);
        query.whereEqualTo("post", AVUser.getCurrentUser());
        query.whereEqualTo(OperateDBUtils.DATE, date);
        query.findInBackground(new FindCallback<AVObject>() {
            @Override
            public void done(List<AVObject> list, AVException e) {
                if (e == null) {
                    if (list.size() > 0) {
                        for (int i = 0; i < list.size(); i++) {
                            AVObject avObjects = list.get(i);
                            avObjects.put(OperateDBUtils.TOTAL_MILEAGE, travelInfoEntity.getTotalMileage());
                            avObjects.put(OperateDBUtils.TODAY_MILEAGE, travelInfoEntity.getTodayMileage());
                            avObjects.put(OperateDBUtils.AVERAGE_SPEED, travelInfoEntity.getAverageSpeed());
                            avObjects.saveInBackground(saveCallback);
                        }
                    }
                }
            }
        });
    }

    public void addTravelInfoAndTimeToServer(final TravelInfoEntity travelInfoEntity, final Date date, final SaveCallback saveCallback) {
        if (travelInfoEntity == null || date == null) {
            Log.d(TAG, "addTravelInfoAndTimeToServer travelInfoEntity =  " + travelInfoEntity + " , date = " + date);
            return;
        }

        AVObject postTotalMileage = new AVObject(TRAVEL_INFO);
        postTotalMileage.put("post", AVUser.getCurrentUser());
        postTotalMileage.put(OperateDBUtils.DATE, date);
        postTotalMileage.put(OperateDBUtils.TOTAL_MILEAGE, travelInfoEntity.getTotalMileage());
        postTotalMileage.put(OperateDBUtils.TODAY_MILEAGE, travelInfoEntity.getTodayMileage());
        postTotalMileage.put(OperateDBUtils.AVERAGE_SPEED, travelInfoEntity.getAverageSpeed());
        postTotalMileage.saveInBackground(saveCallback);
    }

    public void saveBlueToothIsBind(final boolean isBind, final String deviceNum, final QueryBabyInfoCallBack.SaveIsBind saveIsBind) {
        if (babyInfoEntity.getBabyInfoObjectId() != null) {
            progressDialog.show();
            AVQuery<AVObject> query = new AVQuery<>(NetWorkRequest.BABY_INFO);
            query.getInBackground(babyInfoEntity.getBabyInfoObjectId(), new GetCallback<AVObject>() {
                @Override
                public void done(AVObject avObject, AVException e) {
                    if (e == null) {
                        postIsBind = avObject;
                        postIsBind.put(OperateDBUtils.IS_BIND, isBind);
                        postIsBind.put(OperateDBUtils.BLUETOOTH_DEVICE_ID, deviceNum);
                        postIsBind.saveInBackground(new SaveCallback() {
                            @Override
                            public void done(AVException e) {
                                progressDialog.dismiss();
                                if (e == null) {
                                    mOperateDBUtils.saveBlueToothIsBindToDB(isBind, deviceNum);
                                    babyInfoEntity.setIsBind(isBind ? 1 : 0);
                                    babyInfoEntity.setBluetoothDeviceId(deviceNum);
                                    if (saveIsBind != null) {
                                        saveIsBind.finishSaveIsBindSuccess(isBind, deviceNum);
                                    }
                                } else {
                                    if (saveIsBind != null) {
                                        saveIsBind.finishSaveIsBindFail();
                                    }
                                    if (isBind) {
                                        Toast.makeText(mContext, "解除绑定蓝牙失败,请检测网络状况!", Toast.LENGTH_SHORT).show();
                                    } else {
                                        Toast.makeText(mContext, "解除绑定蓝牙失败,请检测网络状况!", Toast.LENGTH_SHORT).show();
                                    }
                                }
                            }
                        });
                    } else {
                        progressDialog.dismiss();
                        if (saveIsBind != null) {
                            saveIsBind.finishSaveIsBindFail();
                        }
                        if (isBind) {
                            Toast.makeText(mContext, "解除绑定蓝牙失败,请检测网络状况!", Toast.LENGTH_SHORT).show();
                        } else {
                            Toast.makeText(mContext, "解除绑定蓝牙失败,请检测网络状况!", Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            });
        } else {
            if (isBind) {
                Toast.makeText(mContext, "解除绑定蓝牙失败,请稍后再试!", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(mContext, "解除绑定蓝牙失败,请稍后再试!", Toast.LENGTH_SHORT).show();
            }
        }
    }

    public void getHealthStateDataFromServer(String sex, String age, FindCallback<AVObject> findCallback) {
        AVQuery<AVObject> query = AVQuery.getQuery(HEALTH_STATE);
        query.whereEqualTo("sex", sex);
        query.whereEqualTo("age", age);
        query.findInBackground(findCallback);
    }

    private void initProgressDialog() {
        if (mContext == null) {
            progressDialog = new ProgressDialog(MyApplication.getInstance().getApplicationContext());
        } else {
            progressDialog = new ProgressDialog(mContext);
        }
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.setMessage("保存中，请稍后...");
        progressDialog.setIndeterminate(false);
        progressDialog.setCancelable(true);
        progressDialog.setCanceledOnTouchOutside(false);
    }

    public ProgressDialog getProgressDialog() {
        return progressDialog;
    }

    public boolean isNetworkConnected() {
        ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getActiveNetworkInfo();
        return ni != null && ni.isConnectedOrConnecting();
    }
}
